package com.bosch.in.rtp1.ept.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONSerializer;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.MappingDispatchAction;

import com.bosch.in.rtp1.ept.constant.CommonConstants;
import com.bosch.in.rtp1.ept.constant.HCFilterColumnName;
import com.bosch.in.rtp1.ept.constant.HoldCodeType;
import com.bosch.in.rtp1.ept.constant.QueryKeyWord;
import com.bosch.in.rtp1.ept.manager.HoldCodeFilterManager;
import com.bosch.in.rtp1.ept.model.dto.HoldCodeFilter;
import com.bosch.in.rtp1.ept.model.dto.JqgridJsonData;
import com.bosch.in.rtp1.ept.util.ConverterUtility;
import com.bosch.in.rtp1.ept.util.HoldCodeUtility;
import com.bosch.in.rtp1.ept.util.ManagerFactory;
import com.bosch.in.rtp1.ept.util.StringUtility;

/**
 * 
 *
 *
 */
public class HCFilterCustomizedAction extends MappingDispatchAction {


	/**
	 * request parameter name to indicate user activity which may be delete, insert, update, reorder.
	 */
	private static final String OPERATION = "oper";
	
	private static final String UPDATE = "edit";
	
	private static final String INSERT = "add";
	
	private static final String DELETE = "del";
	
	private static final String REORDER = "reorder";
	
	/**
	 * parameter name used to store new order list of HoldCodeFilter values
	 */
	private static final String ORDER = "order";
	
	/**
	 * Message is showed to user to indicate if action is successful or not
	 */
	private static final String UPDATE_SUC_MSG = "{\"success\": true, \"message\": \"Update successfully!\"}";
	private static final String UPDATE_FAIL_MSG = "{\"success\":false,\"message\":\"The comment is duplicated. Please change the comment.\"}";
	private static final String UPDATE_SPC_HC_FAIL_MSG = "{\"success\":false,\"message\":\"Unable to update hold code for special comment (?).\"}";
	
	private static final String INSERT_SUC_MSG = "{\"success\": true, \"message\": \"Insert successfully!\"}";
	private static final String INSERT_FAIL_MSG = "{\"success\":false,\"message\":\"The comment is duplicated. Please change the comment.\"}";
	private static final String INSERT_SPC_HC_FAIL_MSG = "{\"success\":false,\"message\":\"Unable to insert hold code for special comment (?).\"}";
	
	private static final String DELETE_SUC_MSG = "{\"success\": true, \"message\": \"Delete successfully!\"}";
	private static final String DELETE_FAIL_MSG = "{\"success\":false,\"message\":\"Delete fail.\"}";
	
	private static final String REORDER_SUC_MSG = "reorder successfully!";
	private static final String REORDER_FAIL_MSG = "<font color='red'>reoder fail!</font>";
	
	
	private static final Logger LOGGER = Logger.getLogger(HCFilterCustomizedAction.class);
	
	// request parameter value for HoldCode table
	//public static final String HC_FILTER = "hcfilter";
	
	/**
	 * Title to distinguish HoldCode table and HoldCode Reclassified table
	 */
	public static final String TITLE = "title";
	private static final String HC_TITLE = "HOLD CODE TABLE";
	private static final String HCRECLS_TITLE = "HOLD CODE GROUPING TABLE";
	private static final String ACTIVEHC_TITLE = "ACTIVE HOLD CODE TABLE";
	
	public static final String ADD_BUTTON = "addButton";
	public static final String DELETE_BUTTON = "deleteButton";
	
    /**
     * Constructor for HCFilterCustomizedAction.
     */
    public HCFilterCustomizedAction() {
        super();
    }

    // ---------------------------------------------------------- Action Methods

    /**
     *
     * @param mapping The ActionMapping used to select this instance
     * @param form The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception Exception if an exception occurs
     *
     * @return the ActionForward to forward control to
     */
    public ActionForward displayHCFilter(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response)
        {
    	LOGGER.debug("Begin HCFilterCustomizedAction.displayHCFilter");
    	
    	// distinguish HoldCode table with HoldCode reclassified table 
    	identifyHoldCodeType(request);
    	
    	LOGGER.debug("End HCFilterCustomizedAction.displayHCFilter");
    	
        // Forward to form page
        return mapping.findForward("success");
    }

    /**
     * distinguish HoldCode table with HoldCode reclassified table 
     * @param request
     * @return
     */
	private HoldCodeType identifyHoldCodeType(HttpServletRequest request) {
    	HoldCodeType hcType;
    	// set title
    	// set flag to distinguish HoldCode table with HoldCode reclassified table
    	if (request.getParameter(CommonConstants.COMMAND).equals(CommonConstants.HC_FILTER)) {
    		request.setAttribute(TITLE, HC_TITLE);
    		request.setAttribute(CommonConstants.COMMAND, CommonConstants.HC_FILTER);
    		// enable add, delete button
    		request.setAttribute(ADD_BUTTON, true);
    		request.setAttribute(DELETE_BUTTON, true);
    		hcType = HoldCodeType.HC;
    	} else if (request.getParameter(CommonConstants.COMMAND).equals(CommonConstants.HC_RECLASS)){
    		request.setAttribute(TITLE, HCRECLS_TITLE);
    		request.setAttribute(CommonConstants.COMMAND, request.getParameter(CommonConstants.COMMAND));
    		// enable add, delete button
    		request.setAttribute(ADD_BUTTON, true);
    		request.setAttribute(DELETE_BUTTON, true);
    		hcType = HoldCodeType.HC_RECLASF;
    	} else {
    		request.setAttribute(TITLE, ACTIVEHC_TITLE);
    		request.setAttribute(CommonConstants.COMMAND, request.getParameter(CommonConstants.COMMAND));
    		// disable add, delete button
    		request.setAttribute(ADD_BUTTON, false);
    		request.setAttribute(DELETE_BUTTON, false);
    		hcType = HoldCodeType.HC_ACTIVE;
    	}
		return hcType;
	}

    /**
    *
    * @param mapping The ActionMapping used to select this instance
    * @param form The optional ActionForm bean for this request (if any)
    * @param request The HTTP request we are processing
    * @param response The HTTP response we are creating
    *
    * @exception Exception if an exception occurs
    *
    * @return the ActionForward to forward control to
     * @throws SQLException 
     * @throws IOException 
    */
   @SuppressWarnings("unchecked")
public ActionForward reloadHCFilter(
       ActionMapping mapping,
       ActionForm form,
       HttpServletRequest request,
       HttpServletResponse response) throws SQLException, IOException
       {
	   LOGGER.debug("Begin HCFilterCustomizedAction.reloadHCFilter");
	   
	   	// get HoldCodeFilterManager instance
	   	HoldCodeFilterManager holdCodeFilterManager = ManagerFactory.getInstance().getHoldCodeFilterManager();
	   	
	 // distinguish HoldCode table with HoldCode reclassified table 
    	HoldCodeType hcType = identifyHoldCodeType(request);
	   	
	   	/* query all HoldCode filter values */
	   	List<HoldCodeFilter> holdCodeFilters = holdCodeFilterManager.getHoldCodeFilters(hcType);
	   	
	   	/* total records */
    	int totalRecords = holdCodeFilters.size();
    	
    	// convert returned data in kind of JSON format which Jqgrid supports
    	JSONArray cellarray = ConverterUtility.convertToHCF_JSONRows(holdCodeFilters);
    	JqgridJsonData jLotStatuses = new JqgridJsonData();
    	jLotStatuses.setPage(1);
    	jLotStatuses.setRecords(totalRecords);
    	jLotStatuses.setRowNum(totalRecords);
    	jLotStatuses.setRows(cellarray);
    	
    	// write data to output stream with MIME type is text
    	//JSONSerializer serializer = new JSONSerializer();  
    	String jsonResponse = JSONSerializer.toJSON(jLotStatuses).toString();
    	response.setContentType("text/html;charset=utf-8");
    	response.setHeader("cache-control", "no-cache");
    	PrintWriter out = response.getWriter();
    	out.println(jsonResponse);
    	out.flush();
    	
    	LOGGER.debug("End HCFilterCustomizedAction.reloadHCFilter");
    	
		return null;
   	
   }

    
    /**
    *
    * @param mapping The ActionMapping used to select this instance
    * @param form The optional ActionForm bean for this request (if any)
    * @param request The HTTP request we are processing
    * @param response The HTTP response we are creating
    *
    * @exception Exception if an exception occurs
    *
    * @return the ActionForward to forward control to
    * @throws IOException 
    * @throws SQLException 
    */
   public ActionForward manipulateHCFilter(
       ActionMapping mapping,
       ActionForm form,
       HttpServletRequest request,
       HttpServletResponse response) throws IOException, SQLException
        {
	   LOGGER.debug("Begin HCFilterCustomizedAction.manipulateHCFilter");
	   
		// get HoldCodeFilterManager instance
		HoldCodeFilterManager holdCodeFilterManager = ManagerFactory.getInstance().getHoldCodeFilterManager();
		
		// detect user operation
		String operation = request.getParameter(OPERATION);
		if (operation.equals(INSERT)) {
			addHCFilter(holdCodeFilterManager, request, response);
		} else if (operation.equals(UPDATE)) {
			updateHCFilter(holdCodeFilterManager, request, response);
		} else if (operation.equals(DELETE)) {
			deleteHCFilter(holdCodeFilterManager, request, response);
		} else if (operation.equals(REORDER)) {
			reorderHCFilter(holdCodeFilterManager, request, response);
		}
		LOGGER.debug("End HCFilterCustomizedAction.manipulateHCFilter");
		return null;
   }
   
   /**
    * 
    * @param holdCodeFilterManager
    * @param request
    * @param response
    * @throws IOException 
    */
	private void updateHCFilter(HoldCodeFilterManager holdCodeFilterManager,
			HttpServletRequest request, HttpServletResponse response) throws IOException
			{
		LOGGER.debug("Begin HCFilterCustomizedAction.updateHCFilter");

		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();

		/* extract parameter from request and build HoldCodeFilter object */
		HoldCodeFilter hcFilter = ConverterUtility.convertToHCFilter(request);

		boolean isValid = checkSpecialHoldCode(hcFilter);
		if (!isValid) {
			out.println(UPDATE_SPC_HC_FAIL_MSG.replace(QueryKeyWord.PLACEHOLDER, hcFilter.getComment()));
		} else {

			List<HoldCodeFilter> hcFilters = new ArrayList<HoldCodeFilter>();
			hcFilters.add(hcFilter);
			boolean success = false;
			try {
				success = holdCodeFilterManager.updateHoldCodeFilter(hcFilters);
			} catch (Exception e) {
				//System.out.println(e.getMessage());
				LOGGER.error(e.getMessage());
			}

			if (success) {
				out.println(UPDATE_SUC_MSG);
			} else {
				out.println(UPDATE_FAIL_MSG);
			}

		}
		out.flush();
		LOGGER.debug("End HCFilterCustomizedAction.updateHCFilter");
	}
   
   /**
    * 
    * @param holdCodeFilterManager
    * @param request
    * @param response
    * @throws IOException 
    */
   private void addHCFilter(HoldCodeFilterManager holdCodeFilterManager, HttpServletRequest request,
		   HttpServletResponse response) throws IOException {
	   LOGGER.debug("Begin HCFilterCustomizedAction.addHCFilter");
	   
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();

		/* extract parameter from request and build HoldCodeFilter object */
		HoldCodeFilter hcFilter = ConverterUtility.convertToHCFilter(request);

		boolean isValid = checkSpecialHoldCode(hcFilter);
		if (!isValid) {
			out.println(INSERT_SPC_HC_FAIL_MSG.replace(QueryKeyWord.PLACEHOLDER, hcFilter.getComment()) );
		} else {

			int newId = 0;
			try {
				newId = holdCodeFilterManager.insertHoldCodeFilter(hcFilter);
			} catch (Exception e) {
				//System.out.println(e.getMessage());
				LOGGER.error(e.getMessage());
			}

			if (newId > 0) {
				out.println(INSERT_SUC_MSG);
			} else {
				out.println(INSERT_FAIL_MSG);
			}
		}

		out.flush();
		LOGGER.debug("End HCFilterCustomizedAction.addHCFilter");
	}

   /**
    * Check if special HoldCode is valid or not
    * @param hcFilter
    * @return
    */
   private boolean checkSpecialHoldCode(HoldCodeFilter hcFilter) {
		boolean isValid = true;
		// validate special HoldCode
		if (hcFilter.getComment().equals(HoldCodeUtility.CLUSTER) || hcFilter.getComment().equals(HoldCodeUtility.REST)) {
			if (hcFilter.getPatternsInStr() != null && !hcFilter.getPatternsInStr().isEmpty()) {
				isValid = false;
			}
		}
		return isValid;
   }
   
   /**
    * 
    * @param holdCodeFilterManager
    * @param request
    * @param response
    * @throws IOException 
    */
   private void deleteHCFilter(HoldCodeFilterManager holdCodeFilterManager, HttpServletRequest request,
		   HttpServletResponse response) throws IOException {
		LOGGER.debug("Begin HCFilterCustomizedAction.deleteHCFilter");
		boolean success = false;
		try {
			int hcFilterId = Integer.parseInt(request.getParameter(HCFilterColumnName.ID.toLowerCase()));
			success = holdCodeFilterManager.deleteHoldCodeFilter(hcFilterId);
		} catch (Exception e) {
			// Just id is invalid. Don't throw exception
		}
		
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		if (success) {
			out.println(DELETE_SUC_MSG);
		} else {
			out.println(DELETE_FAIL_MSG);
		}

		out.flush();
		LOGGER.debug("End HCFilterCustomizedAction.deleteHCFilter");
   }
   
   /**
    * 
    * @param holdCodeFilterManager
    * @param request
    * @param response
    * @throws SQLException 
    * @throws IOException 
    */
   private void reorderHCFilter(HoldCodeFilterManager holdCodeFilterManager, HttpServletRequest request,
		   HttpServletResponse response) throws SQLException, IOException {
	    LOGGER.debug("Begin HCFilterCustomizedAction.reorderHCFilter");
		String orderList = request.getParameter(ORDER);
		List<Integer> orders = StringUtility.extractOrder(orderList);
		boolean success = holdCodeFilterManager.reorderHoldCodeFilters(orders);
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		if (success) {
			out.println(REORDER_SUC_MSG);
		} else {
			out.println(REORDER_FAIL_MSG);
		}
			
		out.flush();
		LOGGER.debug("End HCFilterCustomizedAction.reorderHCFilter");
   }
}
